﻿using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

using Cherry.Agile.ServiceModel.Interceptor;
using Cherry.Agile.Security;
using System.Diagnostics;

namespace Cherry.Agile.ServiceModel.Interceptor
{
    /// <summary>
    /// <see cref="System.ServiceModel.Description.IOperationBehavior"/>的实现
    /// </summary>
    [AttributeUsage(AttributeTargets.Method)]
    public class OperationInterceptorAttribute : Attribute, IOperationBehavior
    {
        private string m_operationMethod = "";

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="operationMethod">方法名称</param>
        public OperationInterceptorAttribute(string operationMethod)
        {
            this.m_operationMethod = operationMethod;
        }

        /// <summary>
        /// 构造一个<see cref="Cherry.Agile.ServiceModel.Interceptor.OperationInvoker"/>
        /// </summary>
        /// <param name="oldInvoker">前一个<see cref="System.ServiceModel.Dispatcher.IOperationInvoker"/></param>
        /// <returns><see cref="Cherry.Agile.ServiceModel.Interceptor.OperationInvoker"/></returns>
        protected OperationInvoker CreateInvoker(System.ServiceModel.Dispatcher.IOperationInvoker oldInvoker)
        {
            return new OperationInvoker(oldInvoker, m_operationMethod);
        }

        /// <summary>
        /// 运行时将数据传递给绑定
        /// </summary>
        /// <param name="operationDescription">操作。仅用于检查。如果修改了操作说明，则结果将不确定</param>
        /// <param name="bindingParameters">绑定元素支持该行为所需的对象的集合</param>
        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        {

        }

        /// <summary>
        /// 执行客户端的修改或扩展
        /// </summary>
        /// <param name="operationDescription">操作。仅用于检查。如果修改了操作说明，则结果将不确定</param>
        /// <param name="clientOperation">公开 operationDescription 所描述的操作的自定义属性的运行时对象</param>
        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
            
        }

        /// <summary>
        /// 执行服务的修改或扩展
        /// </summary>
        /// <param name="operationDescription">操作</param>
        /// <param name="dispatchOperation">公开 operationDescription 所描述的操作的自定义属性的运行时对象</param>
        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            System.ServiceModel.Dispatcher.IOperationInvoker oldInvoker = dispatchOperation.Invoker;
            dispatchOperation.Invoker = CreateInvoker(oldInvoker);

            Trace.TraceInformation("OperationInterceptorAttribute\tcreate operation invoker");
        }

        /// <summary>
        /// 确定操作是否满足某些设定条件
        /// </summary>
        /// <param name="operationDescription">操作</param>
        public void Validate(OperationDescription operationDescription)
        {

        }
    }
}
